<template>
  <div class="pannel flex-box col property-pannel">
    <el-collapse v-model="openPannels">
      <el-collapse-item title="表单属性" name="form">
        <el-button type="primary" @click="$emit('save')">更新保存</el-button>
        <el-button @click="backList">返回列表</el-button>
        <el-form>
          <el-form-item label="表单名称">
            <el-input v-model="form.dataFormName"></el-input>
          </el-form-item>
        </el-form>
      </el-collapse-item>
      <el-collapse-item title="布局属性" name="layout">
        <el-button-group>
          <el-button type="danger" @click="handleDelRow">删除整行</el-button>
          <el-button type="warning" @click="handleDelCol">删除本列</el-button>
        </el-button-group>
        <el-form label-position="left" label-width="5em">
          <el-form-item label="ID">
            <el-input v-model="col.id"></el-input>
          </el-form-item>
          <el-form-item label="宽度">
            <el-input-number v-model="col.span" :min="1" :max="castOverCols"></el-input-number>
          </el-form-item>
          <el-form-item label="偏移">
            <el-input-number v-model="col.offset" :min="0" :max="castOverCols"></el-input-number>
          </el-form-item>
        </el-form>
      </el-collapse-item>
      <el-collapse-item title="组件属性" name="component">
        <el-form label-position="left" label-width="5em">
          <el-form-item label="组件">{{ col.field.name }} {{ col.field.key }}</el-form-item>
          <el-form-item label="日期类型" v-if="col.field.key === 'date'">
            <el-select v-model="col.field.props.type" clearable>
              <el-option
                v-for="(item, index) in opts.dateType"
                :key="index"
                :label="item.label"
                :value="item.value"
              ></el-option>
            </el-select>
          </el-form-item>
          <template v-if="col.field.key === 'button'">
            <el-form-item label="按钮类型">
              <el-select v-model="col.field.props.type" clearable>
                <el-option
                  v-for="(item, index) in opts.buttonType"
                  :key="index"
                  :label="item.label"
                  :value="item.value"
                ></el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="是否朴素">
              <el-switch v-model="col.field.props.plain"></el-switch>
            </el-form-item>
            <el-form-item label="是否圆角">
              <el-switch v-model="col.field.props.round"></el-switch>
            </el-form-item>
            <el-form-item label="是否圆形">
              <el-switch v-model="col.field.props.circle"></el-switch>
            </el-form-item>
          </template>
          <el-form-item label="是否显示">
            <el-switch v-model="col.field.show"></el-switch>
          </el-form-item>
          <el-form-item label="标签">
            <el-input v-model="col.field.label" clearable></el-input>
          </el-form-item>
          <template v-if="['button'].indexOf(col.field.key) === -1">
            <el-form-item label="字段名">
              <el-input v-model="col.field.field" clearable></el-input>
            </el-form-item>
            <el-form-item label="是否必填">
              <el-switch v-model="col.field.required"></el-switch>
            </el-form-item>
            <el-form-item label="正则校验">
              <el-input v-model="col.field.reg" clearable></el-input>
            </el-form-item>
            <el-form-item label="常用正则">
              <k-select v-model="col.field.reg" :options="opts.reg"></k-select>
            </el-form-item>
            <el-form-item label="校验提示">
              <el-input v-model="col.field.message" clearable></el-input>
            </el-form-item>
            <el-form-item label="默认值">
              <el-input v-model="col.field.valueStr" clearable></el-input>
            </el-form-item>
            <el-form-item label="最小值" v-if="col.field.key === 'number'">
              <el-input-number v-model="col.field.props.min" clearable></el-input-number>
            </el-form-item>
            <el-form-item label="最大值" v-if="col.field.key === 'number'">
              <el-input-number v-model="col.field.props.max" clearable></el-input-number>
            </el-form-item>
            <el-form-item label="占位符" v-if="['select', 'input'].indexOf(col.field.key) !== -1">
              <el-input v-model="col.field.props.placeholder" clearable></el-input>
            </el-form-item>
            <el-form-item
              label="可选项"
              v-if="['select', 'radioGroup', 'checkBoxGroup'].indexOf(col.field.key) !== -1"
            >
              <el-input v-model="col.field.options" clearable></el-input>
            </el-form-item>
          </template>
        </el-form>
      </el-collapse-item>
      <el-collapse-item title="事件监听" name="event">
        <el-form-item
          :label="event[0]"
          v-for="event in Object.entries(col.field.events)"
          :key="'event_' + event[0]"
        >
          <el-input type="textarea" v-model="col.field.events[event[0]]" clearable />
        </el-form-item>
        <el-select :options="opts.events" v-model="currentEvent" placeholder="请选择事件"></el-select>
        <el-select :options="castTargets" v-model="currentTarget" placeholder="请选择目标"></el-select>
        <el-select :options="opts.operates" v-model="currentOperate" placeholder="请选择操作"></el-select>
        <el-button @click="handleAddEvent" type="primary">添加事件</el-button>
      </el-collapse-item>
    </el-collapse>
  </div>
</template>

<script>
import eventLib from './event'
import FormlistAPI from '@/api/formlist'
import FormAPI from '@/api/form'
export default {
  name: 'FormPannel',
  inject: ['backList'],
  props: {
    // 当前列索引
    colIndex: {
      type: Number
    },
    // 当前行索引
    rowIndex: {
      type: Number
    },
    // 当前列
    col: {
      type: Object,
      required: true
    },
    // 当前行
    row: {
      type: Object,
      required: true
    },
    // 表单结构
    form: {
      type: Object,
      required: true
    }
  },
  data() {
    return {
      // 展开面板
      openPannels: ['form', 'layout', 'component'],
      lastOpened: [],
      // 事件库
      events: eventLib.events,
      // 操作库
      operates: eventLib.operates,
      // 当前事件
      currentEvent: '',
      // 当前目标
      currentTarget: '',
      // 当前操作
      currentOperate: '',
      // 表单列表
      formlist: null,
      opts: {
        // 按钮类型
        buttonType: [
          { label: '默认', value: 'default' },
          { label: '主要', value: 'primary' },
          { label: '危险', value: 'danger' }
        ],
        // 常用正则
        reg: [
          { label: '默认', value: '^.*$' },
          { label: '手机号码', value: '^1d{10}$' },
          { label: '电话号码', value: '^((d{3,4}-)|d{3.4}-)?d{7,8}$' },
          { label: '邮箱地址', value: '^w+([-+.]w+)*@w+([-.]w+)*.w+([-.]w+)*$' },
          { label: '中文', value: '[\u4e00-\u9fa5]+' },
          { label: '身份证号码', value: '(^d{15}$)|(^d{18}$)|(^d{17}(d|X|x)$)' },
          { label: '域名', value: '[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?' },
          {
            label: 'IP地址',
            value: '((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))'
          }
        ],
        // 常用事件
        events: eventLib.events.map(item => {
          return { label: item.name, value: item.key }
        }),
        // 常用操作
        operates: eventLib.operates.map(item => {
          return { label: item.name, value: item.key }
        }),
        // 表单列表
        formlist: []
      }
    }
  },
  computed: {
    // 组装事件目标
    castTargets() {
      return this.form.rows
        .map(row => row.cols)
        .flat()
        .map(col => {
          return { label: col.field.label, value: col.field.id }
        })
    },
    // 组装可选字段
    castFields() {
      return this.form.fields.map(item => {
        return { label: item.comment + ' - ' + (item.ext ? '扩展' : '固定'), value: item.name }
      })
    },
    // 计算当前行剩余列宽
    castOverCols() {
      const _this = this
      let res = 24
      if (this.row.cols.length > 1) {
        res -= this.row.cols
          .filter((item, index) => index !== _this.colIndex)
          .map(item => item.span)
          .reduce((prev, item, index, arr) => {
            return prev + item
          })
      }
      return res
    }
  },
  watch: {
    formlist: {
      immediate: true,
      async handler(value, old) {
        const _this = this
        // 当前选中的表单列表
        let formlist = this.opts.formlist.find(item => item.value === value)
        this.col.field.formlist = formlist
        if (formlist) {
          // 解析布局
          let layout = JSON.parse(formlist.dataListLayout)
          let cols = layout
            .filter(item => item.show)
            .map(item => {
              return {
                title: item.comment,
                dataIndex: item.name,
                scopedSlots: { customRender: item.name }
              }
            })
            .sort((prev, next) => prev.order - next.order)
          if (formlist.editFlag) {
            // 获取表单列表对应的自动表单
            let res = await FormAPI.GetByModelId(formlist.dataModelId)
            if (!+res.state) {
              formlist.dataFormId = res.data.dataFormId
              let form = JSON.parse(res.data.dataFormLayout || '[]')
                .map(item => item.cols)
                .flat()
                .map(item => item.field)
              // 给表单列表放置插槽
              cols.forEach(item => {
                _this.col.field.slots[item.scopedSlots.customRender] = form.find(field => field.field === item.scopedSlots.customRender)
              })
            }
          }
          this.col.field.props.columns = cols
        }
      }
    },
    openPannels(value, old) {
      this.lastOpened = old
    }
  },
  mounted() {
    this.handleLoadData()
  },
  methods: {
    //   保存表单
    handleSave() {
      this.$emit('save')
    },
    // 删除列
    handleDelCol() {
      this.$emit('delete-col')
    },
    // 删除行
    handleDelRow() {
      this.$emit('delete-row')
    },
    // 添加事件
    handleAddEvent() {
      if (this.currentEvent && this.currentOperate) {
        let code = this.operates.find(item => item.key === this.currentOperate).invoke
        if (code.indexOf('$target') !== -1 && this.currentTarget) {
          code = code.replace('$target', `'${this.currentTarget}'`)
        }
        this.$set(this.col.field.events, this.currentEvent, code)
      }
    },
    // 加载数据
    async handleLoadData() {
      let res = await FormlistAPI.All()
      if (!+res.state) {
        this.opts.formlist = res.data.map(item => {
          return { ...item, label: item.dataListName, value: item.dataListId }
        })
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.property-pannel {
  overflow: auto;
  padding-left: 10px;
  width: 300px;
  height: 100%;
  .col-pannel {
    width: 99%;
    height: max-content;
  }
  .item-pannel {
    width: 99%;
    height: 100%;
    flex-shrink: 10000;
  }
}
</style>
